package com.base.system.managedBean;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.context.FacesContext;
import javax.faces.context.ResponseStream;
import javax.faces.model.SelectItem;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

import org.operamasks.faces.annotation.Action;
import org.operamasks.faces.annotation.Bind;
import org.operamasks.faces.annotation.DownloadListener;
import org.operamasks.faces.annotation.ManagedBean;
import org.operamasks.faces.annotation.ManagedBeanScope;
import org.operamasks.faces.annotation.SaveState;
import org.operamasks.faces.annotation.SelectItems;
import org.operamasks.faces.component.grid.impl.UIDataGrid;
import org.operamasks.faces.component.grid.provider.GridDataProvider;

import com.base.common.converter.ModulesConverter;
import com.base.commons.SpringBeanHolder;
import com.base.security.SecurityReplace;
import com.base.security.onlineuser.entity.OnlineUser;
import com.base.security.onlineuser.service.IOnlineUserDao;
import com.base.utils.DateUtils;

@ManagedBean(name = "system_listUserLoginRecordsBean", scope = ManagedBeanScope.REQUEST)
public class ListUserLoginRecordsBean {
	private IOnlineUserDao onlineUserDao = SpringBeanHolder
			.getBean("onlineUserDao");
	@Bind(id = "userLoginRecordsGrid", attribute = "binding")
	private UIDataGrid userLoginRecordsGrid;

	// ---查询条件---
	@SaveState
	@Bind(id = "specifiedLoginTime")
	private Date specifiedLoginTime;
	@SaveState
	@Bind(id = "specifiedlogoutTime")
	private Date specifiedlogoutTime;
	@SaveState
	@Bind(id = "userLogName")
	private String userLogName;
	@SaveState
	@Bind(id = "logIP")
	private String logIP;
	@SaveState
	@Bind(id = "visitedModules")
	private String visitedModules;

	@Bind(id = "modules")
	@SelectItems
	private SelectItem[] modules = ModulesConverter.getModulesItems();

	@Bind(id = "userLoginRecordsGrid", attribute = "dataProvider")
	public GridDataProvider getDataProvider() {
		return new GridDataProvider() {

			private String regex = "^[\u0000-\u0fff]+$";

			/**
			 * 通过用户姓名查找
			 * 
			 * @return
			 */
			private String getHQLByUserName() {
				String hql = "select new OnlineUser(u.userName,u.loginTime,u.latestActTime,u.modules,u.loginTimeDate,u.ipAddress) from OnlineUser u,SecurityUser s where u.userName=s.username";
				hql = hql + " and u.latestActTime > ?";
				hql = hql + " and u.loginTime < ?";
				if (userLogName != null && !"".equals(userLogName)) {
					hql = hql + " and s.fullname like '%" + userLogName + "%'";
				}
				if (logIP != null && !"".equals(logIP)) {
					hql = hql + " and u.ipAddress = '" + logIP + "'";
				}
				if (visitedModules != null && !"".equals(visitedModules)) {
					hql = hql + "and (u.modules like " + "'" + visitedModules
							+ "'" + " or " + "u.modules like " + "'%,"
							+ visitedModules + "'" + " or " + "u.modules like "
							+ "'" + visitedModules + ",%'" + " or "
							+ "u.modules like " + "'%," + visitedModules
							+ ",%')";
				}
				return hql;
			}

			/**
			 * 通过用户登录名查找
			 * 
			 * @return
			 */
			private String getHQLByLoginName() {
				String hql = "from OnlineUser user where user.loginId is not null ";
				hql = hql + " and user.latestActTime > ?";
				hql = hql + " and user.loginTime < ?";
				if (userLogName != null && !"".equals(userLogName)) {
					hql = hql + " and user.userName = " + "\'" + userLogName
							+ "\'";
				}
				if (logIP != null && !"".equals(logIP)) {
					hql = hql + " and user.ipAddress = " + "\'" + logIP + "\'";
				}
				if (visitedModules != null && !"".equals(visitedModules)) {
					hql = hql + " and (user.modules like " + "'"
							+ visitedModules + "'" + " or "
							+ "user.modules like " + "'%," + visitedModules
							+ "'" + " or " + "user.modules like " + "'"
							+ visitedModules + ",%'" + " or "
							+ "user.modules like " + "'%," + visitedModules
							+ ",%')";
				}
				return hql;
			}

			public Object[] getElements() {
				String hql = "";
				List<OnlineUser> users = new ArrayList<OnlineUser>();
				if (userLogName != null && !userLogName.matches(regex)) {
					hql = this.getHQLByUserName();
				} else {
					hql = this.getHQLByLoginName();
				}
				if (specifiedLoginTime == null || "".equals(specifiedLoginTime))
					specifiedLoginTime = DateUtils.getStartOfDay(DateUtils
							.getDate("1900-1-1"));
				if (specifiedlogoutTime == null
						|| "".equals(specifiedlogoutTime))
					specifiedlogoutTime = DateUtils.getEndOfDay(new Date());
				users = onlineUserDao.findByHql(start, limit, hql, DateUtils
						.getCalendarFromDate(DateUtils
								.getStartOfDay(specifiedLoginTime)), DateUtils
						.getCalendarFromDate(DateUtils
								.getEndOfDay(specifiedlogoutTime)));
				return users.toArray();
			}

			@Override
			public int getTotalCount() {
				if (specifiedLoginTime == null || "".equals(specifiedLoginTime))
					specifiedLoginTime = DateUtils.getStartOfDay(DateUtils
							.getDate("1900-1-1"));
				if (specifiedlogoutTime == null
						|| "".equals(specifiedlogoutTime))
					specifiedlogoutTime = DateUtils.getEndOfDay(new Date());
				// ----通过getCountByHql方法来得到查询到得记录总数,返回的是一个int类型的数据
				// String hql = "select count(*) " + this.getTestHQL();
				// return onlineUserDao.getCountByHql(hql, DateUtils
				// .getCalendarFromDate(specifiedLoginTime), DateUtils
				// .getCalendarFromDate(specifiedlogoutTime));
				// -----------------------------------------------------
				String hql = "";
				if (userLogName != null && !userLogName.matches(regex)) {
					hql = this.getHQLByUserName();
				} else {
					hql = this.getHQLByLoginName();
				}
				return onlineUserDao.findByHql(
						hql,
						DateUtils.getCalendarFromDate(DateUtils
								.getStartOfDay(specifiedLoginTime)),
						DateUtils.getCalendarFromDate(DateUtils
								.getEndOfDay(specifiedlogoutTime))).size();
			}

			@Override
			public Object[] getElementsById(String[] id) {
				return onlineUserDao.findByIds(Arrays.asList(id)).toArray();
			}

			@Override
			public Object getElement(int index) {
				String hql = "";
				if (userLogName != null && !userLogName.matches(regex)) {
					hql = this.getHQLByUserName();
				} else {
					hql = this.getHQLByLoginName();
				}
				List<OnlineUser> list = onlineUserDao.findAllByNamedQuery(
						index, 1, hql, DateUtils.getCalendarFromDate(DateUtils
								.getStartOfDay(specifiedLoginTime)), DateUtils
								.getCalendarFromDate(DateUtils
										.getEndOfDay(specifiedlogoutTime)));
				return list.get(0);
			}
		};
	}

	@Action(id = "query")
	public void query() {
		userLoginRecordsGrid.reload();
	}

	@Action(id = "reset")
	public void reset() {
		specifiedLoginTime = null;
		specifiedlogoutTime = null;
		userLogName = null;
		logIP = null;
		visitedModules = null;
		userLoginRecordsGrid.reload();
	}

	@DownloadListener
	private void downloadAll(FacesContext context, ResponseStream stream)
			throws Exception {
		String innerHql = "select new OnlineUser(u.userName,u.loginTime,u.latestActTime,u.modules,u.loginTimeDate,u.ipAddress) from OnlineUser u";

		List<OnlineUser> users = onlineUserDao.findByHql(innerHql);
		System.out.println(users.size());
		Object data[] = users.toArray();
		commonExport(context, stream, data);
	}

	private void commonExport(FacesContext context, ResponseStream stream,
			Object[] data) {
		if (data == null)
			return;
		WritableWorkbook wwb = null;
		try {
			wwb = Workbook.createWorkbook(stream);
			WritableSheet ws = wwb.createSheet("用户登录记录", 0);

			// 写入表头
			Label labelItem = new Label(0, 0, "用户登录名");
			ws.addCell(labelItem);
			labelItem = new Label(1, 0, "用户姓名");
			ws.addCell(labelItem);
			labelItem = new Label(2, 0, "登录时间");
			ws.addCell(labelItem);
			labelItem = new Label(3, 0, "离线时间");
			ws.addCell(labelItem);
			labelItem = new Label(4, 0, "在线时间");
			ws.addCell(labelItem);
			labelItem = new Label(5, 0, "用户IP");
			ws.addCell(labelItem);
			labelItem = new Label(6, 0, "访问模块");
			ws.addCell(labelItem);

			// 写入数据
			for (int i = 0; i < data.length; i++) {
				OnlineUser s = (OnlineUser) data[i];
				labelItem = new Label(0, i + 1, s.getUserName());
				ws.addCell(labelItem);

				labelItem = new Label(1, i + 1, SecurityReplace
						.replaceUserFullNameByUsername(s.getUserName()));
				ws.addCell(labelItem);

				labelItem = new Label(2, i + 1, DateUtils.getTimeString(s
						.getLoginTime().getTime()));
				ws.addCell(labelItem);

				labelItem = new Label(3, i + 1, DateUtils.getTimeString(s
						.getLatestActTime().getTime()));
				ws.addCell(labelItem);

				labelItem = new Label(4, i + 1, this.getTimeValue(s
						.getTimeInterval()));
				ws.addCell(labelItem);

				labelItem = new Label(5, i + 1, s.getIpAddress());
				ws.addCell(labelItem);

				labelItem = new Label(6, i + 1, this.getModulesValue(s
						.getModules()));
				ws.addCell(labelItem);
			}
			wwb.write();
			wwb.close();
			stream.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (RowsExceededException e) {
			e.printStackTrace();
		} catch (WriteException e) {
			e.printStackTrace();
		}
	}

	private String getTimeValue(Long value) {
		long interval = 0;
		if (value instanceof Long) {
			interval = (Long) value;
		}
		long hour = interval / (1000 * 60 * 60);
		long minute = interval % (1000 * 60 * 60) / (1000 * 60);
		long second = interval % (1000 * 60) / (1000);
		StringBuffer buffer = new StringBuffer();
		buffer.append(hour).append("小时").append(minute).append("分").append(
				second).append("秒");
		return buffer.toString();
	}

	private String getModulesValue(Object arg2) {
		if (arg2 != null) {
			String modules = arg2.toString();
			StringBuilder names = new StringBuilder();
			String[] temp = modules.split(",");
			for (int i = 0; i < temp.length; i++) {
				if (i > 0)
					names.append(",");
				if (modulesMap.containsKey(temp[i])) {
					names.append(modulesMap.get(temp[i]));
				}
			}
			return names.toString();
		}
		return null;
	}

	private static Map modulesMap = new HashMap<String, String>();
	static {
		modulesMap.put("system", "系统管理");
		modulesMap.put("home", "系统首页");
		modulesMap.put("portal", "个人首页");
	}
}
